package com.webank.wedatasphere.qualitis.controller.thymeleaf;

import com.alibaba.fastjson.JSONObject;
import com.webank.wedatasphere.qualitis.dao.ClusterInfoDao;
import com.webank.wedatasphere.qualitis.entity.ClusterInfo;
import com.webank.wedatasphere.qualitis.exception.UnExpectedRequestException;
import com.webank.wedatasphere.qualitis.handler.CommonJDBCService;
import com.webank.wedatasphere.qualitis.metadata.client.MetaDataClient;
import com.webank.wedatasphere.qualitis.metadata.exception.MetaDataAcquireFailedException;
import com.webank.wedatasphere.qualitis.metadata.request.GetColumnByUserAndTableRequest;
import com.webank.wedatasphere.qualitis.metadata.request.GetDbByUserAndClusterRequest;
import com.webank.wedatasphere.qualitis.metadata.request.GetTableByUserAndDbRequest;
import com.webank.wedatasphere.qualitis.metadata.response.DataInfo;
import com.webank.wedatasphere.qualitis.metadata.response.column.ColumnInfoDetail;
import com.webank.wedatasphere.qualitis.metadata.response.db.DbInfoDetail;
import com.webank.wedatasphere.qualitis.metadata.response.table.TableInfoDetail;
import com.webank.wedatasphere.qualitis.project.dao.repository.ProjectRelationShipRuleRepository;
import com.webank.wedatasphere.qualitis.response.Grid;
import com.webank.wedatasphere.qualitis.response.Resp;
import com.webank.wedatasphere.qualitis.rule.dao.repository.RuleDataSourceRepository;
import com.webank.wedatasphere.qualitis.rule.dao.repository.RuleDetailInfoVoRepository;
import com.webank.wedatasphere.qualitis.rule.dao.repository.RuleModelRepository;
import com.webank.wedatasphere.qualitis.rule.dao.repository.RuleRepository;
import com.webank.wedatasphere.qualitis.rule.entity.Rule;
import com.webank.wedatasphere.qualitis.rule.entity.RuleDataSource;
import com.webank.wedatasphere.qualitis.rule.entity.RuleDetailInfoVo;
import com.webank.wedatasphere.qualitis.rule.entity.RuleModelInfo;
import com.webank.wedatasphere.qualitis.util.CommUtils;
import com.webank.wedatasphere.qualitis.util.LocalTimeUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 执行规则
 */
@RestController
@RequestMapping(value = {"/ruleManager"})
public class ExecuteRuleController {

    /**
     * 规则操作
     */
    @Autowired
    private CommonJDBCService commonJDBCService;

    @Autowired
    private ProjectRelationShipRuleRepository projectRelationShipRuleRepository;

    /**
     * 规则操作
     */
    @Autowired
    private RuleRepository ruleRepository;


    @Autowired
    private RuleModelRepository ruleModelRepository;

    /**
     * 规则操作--数据源
     */
    @Autowired
    private RuleDataSourceRepository ruleDataSourceRepository;


    @Autowired
    private ClusterInfoDao clusterInfoDao;

    @Autowired
    private MetaDataClient metaDataClient;


    @Autowired
    private RuleDetailInfoVoRepository ruleDetailInfoVoRepository;

    /**
     * List台账
     *
     * @return
     */
    @RequestMapping(value = {"/list"}, method = RequestMethod.GET)
    public ModelAndView list() {
        ModelAndView modelAndView = new ModelAndView("layui-admin/rule/list");
        return modelAndView;
    }

    /**
     * List台账--新表
     *
     * @return
     */
    @RequestMapping(value = {"/list_new"}, method = RequestMethod.GET)
    public ModelAndView list_new() {
        ModelAndView modelAndView = new ModelAndView("layui-admin/rule/list_new");
        return modelAndView;
    }



    /**
     * List台账
     *
     * @return
     */
    @RequestMapping(value = {"/choice"}, method = RequestMethod.GET)
    public ModelAndView choice(HttpServletRequest httpServletRequest) {
        ModelAndView modelAndView = new ModelAndView("layui-admin/rule/choice");
        modelAndView.addObject("BZId", httpServletRequest.getParameter("BZId"));
        return modelAndView;
    }

    /**
     * 根据集群引擎获取数据源--获取数据库
     *
     * @param params params
     * @return Resp
     */
    @RequestMapping(value = {"/getDatabaseByClusterName"}, method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Resp<?> getDatabaseByClusterName(@RequestBody Map<String, String> params, HttpServletRequest request) throws UnExpectedRequestException, MetaDataAcquireFailedException {
        String clusterName = params.get("clusterName");
        GetDbByUserAndClusterRequest getDbByUserAndClusterRequest = new GetDbByUserAndClusterRequest("admin", 0,
                500, clusterName);
        DataInfo<DbInfoDetail> dataInfo = metaDataClient.getDbByUserAndCluster(getDbByUserAndClusterRequest);
        List<DbInfoDetail> allHiveDbInfo = dataInfo.getContent();
        return Resp.Ok(allHiveDbInfo);
    }


    /**
     * 新增数据校验规则
     *
     * @param ruleDetailInfoVo ruleDetailInfoVo
     * @return Resp
     */
    @RequestMapping(value = {"/insertRuleOrUpdate"}, method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    @Transactional
    public Resp<?> insertRule(RuleDetailInfoVo ruleDetailInfoVo, HttpServletRequest request){
       if (ruleDetailInfoVo.getId()== null){
           ruleDetailInfoVo.setCreateTime(LocalTimeUtils.getCurrentTime());
       }
        RuleModelInfo template = ruleModelRepository.findById(Long.parseLong(ruleDetailInfoVo.getRuleTemplateId())).get();
        String name = template.getModelName();
        ruleDetailInfoVo.setRuleTemplate(name);
        ruleDetailInfoVo.setUpdateTime(LocalTimeUtils.getCurrentTime());
        ruleDetailInfoVoRepository.save(ruleDetailInfoVo);
        return Resp.Ok();
    }

    /**
     * 根据集群引擎获取数据源--下面的数据库里面的表
     *
     * @param params params
     * @return Resp
     */
    @RequestMapping(value = {"/getTableByDatabase"}, method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Resp<?> getTableByDatabase(@RequestBody Map<String, String> params, HttpServletRequest request) throws UnExpectedRequestException, MetaDataAcquireFailedException {
        String clusterName = params.get("clusterName");
        String dbName = params.get("dbName");
        GetTableByUserAndDbRequest getTableByUserAndDbRequest = new GetTableByUserAndDbRequest("admin", 0,
                500, clusterName, dbName);
        DataInfo<TableInfoDetail> allTableList = metaDataClient.getTableByUserAndDb(getTableByUserAndDbRequest);
        List<TableInfoDetail> allTables = allTableList.getContent();
        return Resp.Ok(allTables);
    }


    /**
     * 根据集群引擎获取数据源--下面的表---获取下面的字段
     *
     * @param params params
     * @return Resp
     */
    @RequestMapping(value = {"/getColumnByTable"}, method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Resp<?> getColumnByTable(@RequestBody Map<String, String> params, HttpServletRequest request) throws UnExpectedRequestException, MetaDataAcquireFailedException {
        String clusterName = params.get("clusterName");
        String dbName = params.get("dbName");
        String tableName = params.get("tableName");
        GetColumnByUserAndTableRequest getColumnByUserAndTableRequest = new GetColumnByUserAndTableRequest("admin", 0,
                500, clusterName, dbName, tableName);
        DataInfo<ColumnInfoDetail> columnInfoDetailDataInfo = metaDataClient.getColumnByUserAndTable(getColumnByUserAndTableRequest);
        List<ColumnInfoDetail> colDetailList = columnInfoDetailDataInfo.getContent();
        return Resp.Ok(colDetailList);
    }

    /**
     * List台账选择的单个详情
     *
     * @param httpServletRequest
     * @return
     */
    @RequestMapping(value = {"/detail"}, method = RequestMethod.GET)
    public ModelAndView insertsjbz(HttpServletRequest httpServletRequest) throws UnExpectedRequestException, MetaDataAcquireFailedException {
        ModelAndView view = new ModelAndView("layui-admin/rule/detail");
        String id = httpServletRequest.getParameter("id");
        if (StringUtils.isNotBlank(id)) {
            RuleDetailInfoVo ruleDetailInfoVo = ruleDetailInfoVoRepository.getOne(Long.parseLong(id));
            view.addObject("dataInfo", ruleDetailInfoVo);

            // 数据库库名
            GetDbByUserAndClusterRequest getDbByUserAndClusterRequest = new GetDbByUserAndClusterRequest("admin", 0,
                    500, ruleDetailInfoVo.getDataSourceEngine());
            DataInfo<DbInfoDetail> dataInfo = metaDataClient.getDbByUserAndCluster(getDbByUserAndClusterRequest);
            List<DbInfoDetail> allHiveDbInfo = dataInfo.getContent();
            view.addObject("allHiveDbInfo", allHiveDbInfo);

            // 数据库下面的表
            GetTableByUserAndDbRequest getTableByUserAndDbRequest = new GetTableByUserAndDbRequest("admin", 0,
                    500, ruleDetailInfoVo.getDataSourceEngine(), ruleDetailInfoVo.getDatabaseName());
            DataInfo<TableInfoDetail> allTableList = metaDataClient.getTableByUserAndDb(getTableByUserAndDbRequest);
            List<TableInfoDetail> allTables = allTableList.getContent();
            view.addObject("allTableList", allTables);

            // 字段名称
            GetColumnByUserAndTableRequest getColumnByUserAndTableRequest = new GetColumnByUserAndTableRequest("admin", 0,
                    500, ruleDetailInfoVo.getDataSourceEngine(), ruleDetailInfoVo.getDatabaseName(), ruleDetailInfoVo.getTableName());
            DataInfo<ColumnInfoDetail> columnInfoDetailDataInfo = metaDataClient.getColumnByUserAndTable(getColumnByUserAndTableRequest);
            List<ColumnInfoDetail> colDetailList = columnInfoDetailDataInfo.getContent();
            view.addObject("colDetailList", colDetailList);
        } else {
            view.addObject("dataInfo", new RuleDetailInfoVo());
        }
        // hive 数据库单表查询规则类型
        List<RuleModelInfo> ruleTypeList = ruleModelRepository.findAll();
        view.addObject("ruleTypeList", ruleTypeList);
        view.addObject("readOnly",StringUtils.isBlank(httpServletRequest.getParameter("readOnly")));
        // 集群管理
        List<ClusterInfo> allCluster = clusterInfoDao.findAllClusterInfo(0, 500);
        view.addObject("allCluster", allCluster);

        return view;
    }


    /**
     * 删除
     *
     * @param params
     * @return
     */
    @RequestMapping(value = {"/new_remove"},method = RequestMethod.POST)
    @ResponseBody
    public Resp<?> new_remove(@RequestBody Map<String,String> params) {
        if (MapUtils.isEmpty(params)) {
            return Resp.error("id不能为空");
        }
        try {
            String ids = params.get("ids");
            String[] thatIds = ids.split(",");
            for (String id : thatIds) {
                ruleDetailInfoVoRepository.deleteById(Long.valueOf(id));
            }
            return Resp.Ok("删除成功！！！");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Resp.error("删除失败");
    }

    /**
     * EasyUI分页
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/datagridLayUI"}, method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Resp<?> datagridLayUI(HttpServletRequest request) {
        //  分页查询
        int page = Integer.parseInt(request.getParameter("page"));
        String limit = request.getParameter("limit");
        if (StringUtils.isBlank(request.getParameter("BZID"))) {
            return Resp.OkPageLayUI(new ArrayList<>(), 0);
        }
        long bzid = Long.parseLong(request.getParameter("BZID"));
        return commonJDBCService.queryRuleDataGridByPageInSqlWhere(bzid, page, Integer.parseInt(limit));
    }

    /**
     * JDBC分页查询|选择器
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/selectChoice"}, method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Grid<?> selectChoice(HttpServletRequest request) {
        return  Grid.OkPage(new ArrayList<>(), 0);
    }

    /**
     * 根据规则模板获取模板详情
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/getTemplateById"}, method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Resp<?> getTemplateById(@RequestBody Map<String, String> params, HttpServletRequest request) {
        String ruleTemplateId = params.get("ruleTemplateId");
        RuleModelInfo templateInDb = ruleModelRepository.findById(Long.parseLong(ruleTemplateId)).get();
        return Resp.Ok(templateInDb);
    }


    /**
     * EasyUI分页
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/datagrid_new"}, method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Grid<?> datagridNew(HttpServletRequest request) {
        Sort sort = new Sort(Sort.Direction.ASC, "id");
        //  分页查询
        String page = request.getParameter("page");
        String limit = request.getParameter("rows");

        // 获取条件过滤器
        JSONObject changeBuilder = CommUtils.getJsonObject(request);
        // 组装SQl条件过滤法器
        ExampleMatcher matcher = CommUtils.getSqlWhere(request);
        // 序列化对象
        RuleDetailInfoVo itemQueryWhere = changeBuilder.toJavaObject(RuleDetailInfoVo.class);
        // 分页插件
        Pageable pageable = PageRequest.of(Integer.parseInt(page) - 1, Integer.parseInt(limit), sort);
        // 条件过滤器插件
        Example<RuleDetailInfoVo> example = Example.of(itemQueryWhere, matcher);
        // 条件过滤+分页
        Page<RuleDetailInfoVo> all = ruleDetailInfoVoRepository.findAll(example, pageable);
        // 获取数据
        List<RuleDetailInfoVo> content = all.getContent();
        long totalElements = all.getTotalElements();
        return Grid.OkPage(CollectionUtils.isEmpty(content)?new ArrayList<>():content, totalElements);
    }

    /**
     * EasyUI分页
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/datagrid"}, method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Grid<?> datagrid(HttpServletRequest request) {
        Sort sort = new Sort(Sort.Direction.ASC, "id");
        //  分页查询
        String page = request.getParameter("page");
        String limit = request.getParameter("rows");

        // 获取条件过滤器
        JSONObject changeBuilder = CommUtils.getJsonObject(request);
        // 组装SQl条件过滤法器
        ExampleMatcher matcher = CommUtils.getSqlWhere(request);
        // 序列化对象
        Rule itemQueryWhere = changeBuilder.toJavaObject(Rule.class);
        // 分页插件
        Pageable pageable = PageRequest.of(Integer.parseInt(page) - 1, Integer.parseInt(limit), sort);
        // 条件过滤器插件
        Example<Rule> example = Example.of(itemQueryWhere, matcher);
        // 条件过滤+分页
        Page<Rule> all = ruleRepository.findAll(example, pageable);
        // 组装数据源
        for (Rule rule : all) {
            List<RuleDataSource> byRule = ruleDataSourceRepository.findByRule(rule);
            if (CollectionUtils.isNotEmpty(byRule)) {
                rule.setDatasourceName(byRule.get(0).getDbName());
                rule.setDbName(byRule.get(0).getDbName());
                rule.setTableName(byRule.get(0).getTableName());
                rule.setTableFields(byRule.get(0).getColName());
                rule.setSqlWhere(byRule.get(0).getFilter());
            }
        }
        // 获取数据
        List<Rule> content = all.getContent();
        long totalElements = all.getTotalElements();
        return Grid.OkPage(CollectionUtils.isEmpty(content)?new ArrayList<>():content, totalElements);
    }


    /**
     * 删除
     *
     * @param ids
     * @return
     */
    @RequestMapping(value = {"/remove"})
    @ResponseBody
    public Resp<?> remove(@RequestParam("ids") String ids) {
        if (StringUtils.isBlank(ids)) {
            return Resp.error("id不能为空");
        }
        try {
            String[] thatIds = ids.split(",");
            for (String id : thatIds) {
                ruleRepository.deleteById(Long.valueOf(id));
            }
            return Resp.Ok("删除成功！！！");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Resp.error("删除失败");
    }

}
